前幾天大致介紹過如何建立好一個index,以及主要參照的規則,今天則是要介紹各種不同 index 的特性,以及它們各自會用到的場景。
在我們第二天在介紹索引時有提到,MongoDB會自動幫_id
建立unique index,除了可以加快使用_id
搜尋資料的速度以外,還可以確保_id
值不會重複。
事實上unique index也可以用在其他欄位上,只要在建立index時候,多加入unique: true
的設定,詳細語法如下。
// 語法架構
db.collection.createIndex( <key and index type specification>, { unique: true } )
// Single Field Indexes 寫法
product.createIndex( { name: 1 }, { unique: true } )
// Compound Index 寫法
user.createIndex( { name: 1, email: 1 }, { unique: true } )
使用上必須注意,如果建立時索引欄位有重複的值,Unique Indexes無法被建立,以及在寫入資料的時候,如果寫入索引欄位有相同值,也會出錯。
ps.只允許索引欄位有一個值是缺漏的,缺漏的值會用null替代,下一個缺漏再用null替代,就會違反沒有重複的值出現的條件。
因此unique index蠻適合用在,想要避免重複資料寫入的場景,例如:在註冊時想要避免,使用者重複使用相同的信箱註冊,這時候就可以再email這個欄位加上unique index。在使用信箱登入的時候,也可以通過index加快尋找使用者資料的速度。
可以只針對部分資料建立索引,例如:所有商品類別中,只有3C類別的產品賣得最好,最常被消費者搜尋,因此我們只針對3C類別的產品建立price欄位的索引。
這時候可以用以下指令,partialFilterExpression後面寫入資料塞選的條件。
product.createIndex(
{ price: 1 },
{ partialFilterExpression: { category: { $eq: "3C" } } }
)
在使用條件篩選資料時,只能使用以下的操作符
TTl index 這個索引類型,是我覺得在MongoDB蠻特別、也蠻好用的一個功能,它可以讓資料根據特定欄位設定的時間,自動刪除不會用到的資料。
例如:使用者的聊天訊息,我們只想保留6個月,避免資料庫一直寫入太多資料都未清理,節省資料庫的空間,這時候可以使用以下指令。
// 透過 expireAfterSeconds設定資料過期的時間,單位是秒
message.createIndex( { create_time: 1 }, { expireAfterSeconds: 15552000 } )
使用上必須注意
可以暫時隱藏索引,而非實際刪除索引,讓開發人員來評估,使用索引使用索引前後效能差異。
以商品資料做舉例,我們現在有針對price這個欄位做索引。
// 建立索引時,可以透過hidden來設定,是否隱藏索引
product.createIndex(
{ price: 1 },
{ hidden: true }
);
// 可以透過getIndexes來查看,collection目前包含哪些索引,索引是否被隱藏
prodct.getIndexes()
// 回傳結果
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"price" : 1
},
"name" : "price_1",
"hidden" : true // 在這個欄位可以看到索引是否被隱藏
}
]
// 如果想要將隱藏的索引,改成使用索引,可以使用unhideIndex,並帶入索引名稱
product.unhideIndex( "price_1" );
// 如果想要將原本有在使用的索引隱藏,可以使用 hideIndex
product.hideIndex( "price_1" );
使用上必須注意
_id index
本篇文章同步放在我的部落格,大家有空可以進來逛逛